import os.path
import random
import time

from selenium import webdriver
from selenium.common.exceptions import StaleElementReferenceException
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Service


from selenium_utils import SeleniumUtils
from slidevcode.SlideVerifyCode import SlideVerifyCode


# https://blog.51cto.com/u_16099273/6555715
class Zhihu:
    def __init__(self):
        # 尝试传参
        s = Service("chromedriver.exe")
        options = Options()
        # options.add_experimental_option('excludeSwitches', ['enable-automation'])
        # options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")  # 前面设置的端口号
        self.driver = webdriver.Chrome(service=s)
        self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
            "source": """
            Object.defineProperty(navigator, 'webdriver', {
              get: () => undefined
            })
          """
        })
        # self.driver = webdriver.Chrome(service=s, options=chrome_options)
        # driverfile_path = r'./msedgedriver.exe'
        # driver = webdriver.Edge(executable_path=driverfile_path)
        self.driver.maximize_window()  # 最大化窗口

    def start(self, cover, title, theme, desc):
        try:
            # 进入创作者页面
            self.driver.get("https://zhuanlan.zhihu.com/write?" + str(random.random()))
            if os.path.exists("./cookies/zhihu.pkl"):
                SeleniumUtils.load_cookie(self.driver, ".zhihu.com", "./cookies/zhihu.pkl")
                self.driver.refresh()
            SeleniumUtils.watting_visibility(self.driver, By.TAG_NAME, "body")
            is_load = SeleniumUtils.is_loaded(self.driver)
            if not is_load:
                print("页面加载失败！")
                return "页面加载失败"
            e_login = None
            try:
                e_login = SeleniumUtils.watting_existed(self.driver, By.XPATH,
                                                      "//*[@id='root']/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[1]/div[2]")
            except Exception as e:
                print(e)

            if e_login is not None:
                e_login.click()
                self.driver.implicitly_wait(1)
                return self.do_login(cover, title, theme, desc)
            # else:
            #     return self.do_publish(cover, title, theme, desc)
        except Exception as e:
            print(e)
            self.driver.quit()
            return e

    def do_login(self, cover, title, theme, desc):
        self.driver.find_element(By.XPATH,
                                 value="//*[@id='root']/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[2]/div/label/input").send_keys(
            "xxxxxxx")
        self.driver.find_element(By.XPATH,
                                 "//*[@id='root']/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[3]/div/label/input").send_keys(
            "xxxxxxx")
        time.sleep(2)
        SeleniumUtils.move_click_by(self.driver, By.XPATH,
                                  "//*[@id='root']/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/button",
                                  5)
        ele_pop = SeleniumUtils.watting_visibility(self.driver, By.XPATH,
                                                 "/html/body/div[4]/div[2]/div/div/div[2]/div/div[1]/div/div[1]/img[1]",
                                                 5)
        exec_count = 0
        while exec_count < 5:
            if ele_pop.is_displayed() and ele_pop.is_enabled():
                exec_count = 6
                break
            print("滑块验证码执行第{}次：".format(exec_count))
            SeleniumUtils.move_click_by(self.driver, By.XPATH,
                                      "//*[@id='root']/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/button",
                                      5)
            exec_count += 1
            time.sleep(1)
        if exec_count != 6:
            print("滑块验证码执行失败！")
            return "破解滑块验证码失败"

        # 4、模拟滑动验证
        # # # 4.1切换到滑动验证码的iframe中
        # tcaptcha = self.driver.find_element(By.XPATH, "//*[@id='ariao1t6p6smqwg']")
        # self.driver.switch_to.frame(tcaptcha)

        # 4.2 获取滑动相关的元素
        # 选择拖动滑块的节点
        slide_element = self.driver.find_element(By.XPATH, '/html/body/div[4]/div[2]/div/div/div[2]/div/div[2]/div[2]')
        # 获取滑块图片的节点
        slideBlock_ele = self.driver.find_element(By.XPATH,
                                                  '/html/body/div[4]/div[2]/div/div/div[2]/div/div[1]/div/div[1]/img[2]')
        # 获取缺口背景图片节点
        slideBg = self.driver.find_element(By.XPATH,
                                           '/html/body/div[4]/div[2]/div/div/div[2]/div/div[1]/div/div[1]/img[1]')
        # 4.3计算滑动距离
        sc = SlideVerifyCode()

        distance = sc.get_element_slide_distance(slideBlock_ele, slideBg)
        # 滑动距离误差校正，滑动距离*图片在网页上显示的缩放比-滑块相对的初始位置
        print("校正后的滑动距离", distance)
        # 4.4、进行滑动
        sc.slide_verification(self.driver, slide_element, distance + 6)

        # 等待登录完成
        ret = SeleniumUtils.watting_visibility(self.driver, By.XPATH,
                                             "//*[@id='root']/div/main/div/div[1]/div/div[1]/div[1]/div/div", 30)
        if ret is None:
            print("登录失败！")
            return "登录失败"

        # cookie.pkl文件
        SeleniumUtils.save_cookie(self.driver, "./cookies/zhihu.pkl")
        return self.do_publish(cover, title, theme, desc)

    def do_publish(self, cover, title, theme, desc):

        # 尝试保存时发生错误：我们检测到您此次登录异常，请您进行安全验证。，无法保存
        # 填充标题
        self.driver.find_element(By.XPATH,
                                 value="//*[@id='root']/div/main/div/div[2]/div[2]/div[1]/label").send_keys(
            title)
        time.sleep(1)
        # 填充描述
        ele_desc = self.driver.find_element(By.XPATH,
                                            '//*[@id="root"]/div/main/div/div[2]/div[2]/div[2]/div[1]/div/div[1]/div/div[2]/div/div/div/div/span')
        ele_desc.send_keys(desc)

        SeleniumUtils.move_click(self.driver, ele_desc)
        SeleniumUtils.scroll_bottom(self.driver)

        # 添加话题并填充
        time.sleep(2)
        # parent = self.driver.find_element(By.XPATH,
        #                                   '//*[@id="root"]/div/main/div/div[2]/div[2]/div[2]/div[3]/div[5]/div/div')
        # ele_closes = parent.find_elements(By.CLASS_NAME,"css-1z01q9l")
        # if ele_closes is not None:
        #     for i in range(len(ele_closes)):
        #         ele_close = ele_closes[i]
        #         try:
        #             ele = ele_close.find_element(By.CLASS_NAME,"css-1uxta5d")
        #             if not ele.is_displayed() or not ele.is_enabled():
        #                 continue
        #             # 在每次循环中操作元素
        #             SeleniumUtils.move_click(self.driver, ele, offset=1)
        #             time.sleep(1)
        #         except StaleElementReferenceException:
        #             # 处理 "stale element reference" 错误
        #             continue
        #
        # time.sleep(2)
        # SeleniumUtils.move_click_by(self.driver, By.XPATH,
        #                           '//*[@id="root"]/div/main/div/div[2]/div[2]/div[2]/div[3]/div[5]/div/div/button')
        # time.sleep(2)
        # self.driver.find_element(By.XPATH,
        #                          '//*[@id="root"]/div/main/div/div[2]/div[2]/div[2]/div[3]/div[5]/div/div/label').send_keys(
        #     theme)
        # time.sleep(1)
        # 填充封面
        if cover is not None and os.path.exists(cover):
            self.driver.find_element(By.XPATH,
                                     '//*[@id="root"]/div/main/div/div[2]/div[2]/div[2]/div[3]/div[2]/div/div/label/input[@type="file"]').send_keys(
                cover)
            time.sleep(2)

        # 发布文章
        SeleniumUtils.move_click_by(self.driver, By.XPATH,
                                  '//*[@id="root"]/div/main/div/div[2]/div[2]/div[2]/div[3]/div[9]/div/button[2]')

        # 等待发布完成
        ret = SeleniumUtils.watting_visibility(self.driver, By.XPATH, "//*[@id='root']/div/main/div/article/header/h1",
                                             30)
        if ret is None:
            print("发布失败")
            return "发布失败"
        return ""


if __name__ == "__main__":
    douyin = Zhihu()
    # 基本信息
    # 视频存放路径
    cover = r"C:\workspace\python\zimeiti\assets\1076.png"
    # cover = None
    title = "自动化测试开发"
    # 视频描述
    desc = "裸眼3D看蜘蛛侠 #搞笑 #电影 #视觉震撼"
    theme = "自动化测试"
    douyin.start(cover, title, theme, desc)
